package com.msh.platform.elm.controller;

import com.msh.platform.bizmedia.base.conf.ResponseResult;
import com.alibaba.fastjson.JSONObject;
import com.msh.platform.elm.common.constants.Constants;
import com.msh.platform.elm.common.constants.SellerStatus;
import com.msh.platform.elm.common.constants.WxPubNoStatus;
import com.msh.platform.elm.entity.AdmUser;
import com.msh.platform.elm.entity.CfgArea;
import com.msh.platform.elm.entity.SellerInfo;
import com.msh.platform.elm.entity.WxPubNo;
import com.msh.platform.elm.entity.WxPubNoExam;
import com.msh.platform.elm.entity.CfgMessage;
import com.msh.platform.elm.entity.OperLog;
import com.msh.platform.elm.service.AdmUserService;
import com.msh.platform.elm.service.CfgAreaService;
import com.msh.platform.elm.service.CfgMessageService;
import com.msh.platform.elm.service.OperLogService;
import com.msh.platform.elm.service.SellerService;
import com.msh.platform.elm.service.WxPubNoExamService;
import com.msh.platform.elm.service.WxPubNoService;
import com.msh.platform.elm.vo.AdmLoginVO;
import com.msh.platform.elm.vo.AdmUserVO;
import com.msh.platform.elm.vo.TokenVO;
import com.msh.platform.elm.vo.WxPubNoExamVO;
import com.msh.platform.elm.vo.ExamPubNoVO;
import com.msh.platform.elm.vo.IdsVO;
import com.msh.platform.elm.vo.PageVO;
import com.msh.platform.elm.vo.SellerInfoRsVO;
import com.msh.platform.elm.common.util.SortUtils;
import com.msh.platform.elm.common.util.MD5;
import com.msh.platform.elm.common.util.MapTrunPojoUtils;

import org.springframework.data.domain.Sort;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import javax.validation.Valid;

/**
 * @Author zhangyangsong
 * @Description :
 * @Date: Created in 2018/11/8
 * @Copyright: ©2018 all rights reserved.
 */
@RestController
@RequestMapping(value = "/adm_user")
@Api(tags = "闽商会管理接口")
@Slf4j
public class AdmUserController extends BaseController{

    @Autowired
    private AdmUserService admUserService;
    @Autowired
    private CfgMessageService cfgMessageService;
    @Autowired
    private CfgAreaService cfgAreaService;
    @Autowired
    private SellerService sellerService;
    @Autowired
    private WxPubNoService wxPubNoService;
    @Autowired
    private OperLogService operLogService;
    @Autowired
    private WxPubNoExamService wxPubNoExamService;
    @Autowired
    private RedisTemplate redisTemplate;

    @ApiOperation(value = "闽商会用户登录")
    @PostMapping(path = "/login")
    public ResponseResult<AdmUserVO> login(@RequestBody @Valid AdmLoginVO paramVo,BindingResult errors) {
    	if (errors.hasErrors()){  //参数校验失败
			//返回参数校验错误信息
	        return ResponseResult.fail(Constants.RESP_FAIL, errors.getAllErrors().get(0).getDefaultMessage());
	    }
    	AdmUserVO admUserVo = new AdmUserVO();
		//校验sign字符串
		Map<String, Object> signMap = MapTrunPojoUtils.object2Map(paramVo);
		signMap.remove("sign");
		String paramStr = SortUtils.sortMap(signMap);
		boolean flag = validateSign(paramStr, paramVo.getSign());
		log.info("验证签名结果：" + flag);
		if(flag){
			String encPwdString = MD5.compile(paramVo.getPasswd() + Constants.PWD_MD5_KEY);
	    	AdmUser admUser = admUserService.getAdmUser(paramVo.getLoginName(),encPwdString);
	    	if(admUser!=null) {
	    		//生成token
				String token = UUID.randomUUID().toString();
				
				//将用户信息写入redis并设置过期时间
				ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
	            operations.set(token, JSONObject.toJSONString(admUser));
	            redisTemplate.expire(token, Constants.TOKEN_EXPIRE_TIME, TimeUnit.MINUTES);
	            
				BeanUtils.copyProperties(admUser,admUserVo);
				admUserVo.setToken(token);
				return ResponseResult.success(admUserVo);
	    	}else {
	    		return ResponseResult.fail(Constants.RESP_FAIL, "登录失败，用户名或密码错误");
	    	}
		}else {
			return ResponseResult.fail(Constants.RESP_FAIL, "签名校验失败");
		}
    }
    
    @ApiOperation(value = "获取消息列表")
    @PostMapping(path = "/get_message_page")
    public ResponseResult<Page<CfgMessage>> get_message_page(@RequestBody @Valid PageVO paramVo, BindingResult errors) {
    	if (errors.hasErrors()){  //参数校验失败
			//返回参数校验错误信息
    		return ResponseResult.fail(Constants.RESP_FAIL, errors.getAllErrors().get(0).getDefaultMessage());
	    }
    	//校验sign字符串
		Map<String, Object> signMap = MapTrunPojoUtils.object2Map(paramVo);
		signMap.put("token", paramVo.getToken());
		String paramStr = SortUtils.sortMap(signMap);
		boolean flag = validateSign(paramStr, paramVo.getSign());
		log.info("验证签名结果：" + flag);
		if(flag){
			Object userObj = getUserByToken(paramVo.getToken());  //通过token获取登录用户
			if(userObj!=null) {  //用户已登录
	    		JSONObject jsonObj = JSONObject.parseObject(userObj.toString());
	    		AdmUser user = JSONObject.toJavaObject(jsonObj, AdmUser.class);
			
	    		Sort sort = new Sort(Sort.Direction.DESC,"createTime"); //创建时间降序排序
	    		Pageable pageable = PageRequest.of(paramVo.getPageNo(), paramVo.getPageSize(), sort);
	    		Page<CfgMessage> messages = cfgMessageService.findByUserId(user.getId(), pageable);
	    		return ResponseResult.success(messages);
			}else {
				return ResponseResult.fail(Constants.RESP_TOKEN_TIMEOUT, "未登录或登录超时");
			}
		}else {
			return ResponseResult.fail(Constants.RESP_FAIL, "签名校验失败");
		}	
    }
    
    @ApiOperation(value = "获取入驻商会列表")
    @PostMapping(path = "/get_seller_page")
    public ResponseResult<Page<SellerInfo>> get_seller_page(@RequestBody @Valid PageVO paramVo,BindingResult errors) {
    	if (errors.hasErrors()){  //参数校验失败
			//返回参数校验错误信息
    		return ResponseResult.fail(Constants.RESP_FAIL, errors.getAllErrors().get(0).getDefaultMessage());
	    }
    	//校验sign字符串
    	Map<String, Object> signMap = MapTrunPojoUtils.object2Map(paramVo);
		signMap.put("token", paramVo.getToken());
		String paramStr = SortUtils.sortMap(signMap);
		boolean flag = validateSign(paramStr, paramVo.getSign());
		log.info("验证签名结果：" + flag);
		if(flag){
			Object userObj = getUserByToken(paramVo.getToken());
			if(userObj!=null) {
			
	    		Sort sort = new Sort(Sort.Direction.DESC,"createTime"); //创建时间降序排序
	    		Pageable pageable = PageRequest.of(paramVo.getPageNo(), paramVo.getPageSize(), sort);
	    		Page<SellerInfo> sellerList = sellerService.findAll(pageable);
	    		return ResponseResult.success(sellerList);
			}else {
				return ResponseResult.fail(Constants.RESP_TOKEN_TIMEOUT, "未登录或登录超时");
			}
		}else {
			return ResponseResult.fail(Constants.RESP_FAIL, "签名校验失败");
		}	
    }
    
    @ApiOperation(value = "获取商会详情")
    @PostMapping(path = "/get_seller_detail/{id}")
    public ResponseResult<SellerInfoRsVO> get_seller_detail(@PathVariable int id, @RequestBody @Valid TokenVO paramVo, BindingResult errors) {
    	if (errors.hasErrors()){  //参数校验失败
			//返回参数校验错误信息
    		return ResponseResult.fail(Constants.RESP_FAIL, errors.getAllErrors().get(0).getDefaultMessage());
	    }
    	//校验sign字符串
    	Map<String, Object> signMap = new HashMap<String, Object>();
		signMap.put("id", id);
		signMap.put("token", paramVo.getToken());
		String paramStr = SortUtils.sortMap(signMap);
		boolean flag = validateSign(paramStr, paramVo.getSign());
		log.info("验证签名结果：" + flag);
		if(flag){
			Object userObj = getUserByToken(paramVo.getToken());
			if(userObj!=null) {
				SellerInfoRsVO sellerInfoRsVO = new SellerInfoRsVO();
	    		SellerInfo sellerInfo = sellerService.getSeller(id);
	    		BeanUtils.copyProperties(sellerInfo, sellerInfoRsVO);
	    		
	    		CfgArea area = cfgAreaService.findById(sellerInfo.getAreaCode());
	    		CfgArea city = cfgAreaService.findById(area.getpId());
	    		CfgArea province = cfgAreaService.findById(city.getpId());
	    		sellerInfoRsVO.setProvince(province.getName());
	    		sellerInfoRsVO.setProvinceId(province.getId());
	    		sellerInfoRsVO.setCity(city.getName());
	    		sellerInfoRsVO.setCityId(city.getId());
	    		sellerInfoRsVO.setArea(area.getName());
	    		return ResponseResult.success(sellerInfoRsVO);
			}else {
				return ResponseResult.fail(Constants.RESP_TOKEN_TIMEOUT, "未登录或登录超时");
			}
		}else {
			return ResponseResult.fail(Constants.RESP_FAIL, "签名校验失败");
		}		
    }
    
    @ApiOperation(value = "封禁商会账号")
    @PostMapping(path = "/disable_seller/{id}")
    public ResponseResult disable_seller(@PathVariable int id,@RequestBody @Valid TokenVO paramVo,BindingResult errors) {
    	if (errors.hasErrors()){  //参数校验失败
			//返回参数校验错误信息
    		return ResponseResult.fail(Constants.RESP_FAIL, errors.getAllErrors().get(0).getDefaultMessage());
	    }
    	//校验sign字符串
    	Map<String, Object> signMap = new HashMap<String, Object>();
		signMap.put("id", id);
		signMap.put("token", paramVo.getToken());
		String paramStr = SortUtils.sortMap(signMap);
		boolean flag = validateSign(paramStr, paramVo.getSign());
		log.info("验证签名结果：" + flag);
		if(flag){
			Object userObj = getUserByToken(paramVo.getToken());
			if(userObj!=null) {
	    		SellerInfo sellerInfo = sellerService.getSeller(id);
	    		sellerInfo.setStatus(SellerStatus.disable.getCode());  //封禁
	    		sellerService.save(sellerInfo);
	    		return ResponseResult.success(null);
			}else {
				return ResponseResult.fail(Constants.RESP_TOKEN_TIMEOUT, "未登录或登录超时");
			}
		}else {
			return ResponseResult.fail(Constants.RESP_FAIL, "签名校验失败");
		}	
    }
    
    @ApiOperation(value = "获取封禁商会列表")
    @PostMapping(path = "/get_disable_seller_page")
    public ResponseResult<Page<SellerInfo>> get_disable_seller_page(@RequestBody @Valid PageVO paramVo,BindingResult errors) {
    	if (errors.hasErrors()){  //参数校验失败
			//返回参数校验错误信息
    		return ResponseResult.fail(Constants.RESP_FAIL, errors.getAllErrors().get(0).getDefaultMessage());
	    }
    	//校验sign字符串
    	Map<String, Object> signMap = MapTrunPojoUtils.object2Map(paramVo);
		signMap.put("token", paramVo.getToken());
		String paramStr = SortUtils.sortMap(signMap);
		boolean flag = validateSign(paramStr, paramVo.getSign());
		log.info("验证签名结果：" + flag);
		if(flag){
			Object userObj = getUserByToken(paramVo.getToken());
			if(userObj!=null) {
			
	    		Sort sort = new Sort(Sort.Direction.DESC,"createTime"); //创建时间降序排序
	    		Pageable pageable = PageRequest.of(paramVo.getPageNo(), paramVo.getPageSize(), sort);
	    		Page<SellerInfo> sellerList = sellerService.findByStatus(SellerStatus.disable.getCode(),pageable);
	    		return ResponseResult.success(sellerList);
			}else {
				return ResponseResult.fail(Constants.RESP_TOKEN_TIMEOUT, "未登录或登录超时");
			}
		}else {
			return ResponseResult.fail(Constants.RESP_FAIL, "签名校验失败");
		}	
    }
    
    @ApiOperation(value = "移除封禁商会")
    @PostMapping(path = "/remove_disable_seller")
    public ResponseResult remove_disable_seller(@RequestBody @Valid IdsVO paramVo,BindingResult errors) {
    	if (errors.hasErrors()){  //参数校验失败
			//返回参数校验错误信息
    		return ResponseResult.fail(Constants.RESP_FAIL, errors.getAllErrors().get(0).getDefaultMessage());
	    }
    	//校验sign字符串
    	Map<String, Object> signMap = new HashMap<String, Object>();
    	ArrayList<Integer> ids = paramVo.getIds();
    	String idsStr = "";
    	for(int i=0;i<ids.size();i++) {
    		if(i < ids.size()-1)
    			idsStr += ids.get(i) + ",";
    		else
    			idsStr += ids.get(i);
    	}
		signMap.put("token", paramVo.getToken());
		signMap.put("ids", idsStr);
		String paramStr = SortUtils.sortMap(signMap);
		boolean flag = validateSign(paramStr, paramVo.getSign());
		log.info("验证签名结果：" + flag);
		if(flag){
			Object userObj = getUserByToken(paramVo.getToken());
			if(userObj!=null) {
	    		List<SellerInfo> sellerList = sellerService.findAllById(paramVo.getIds());
	    		for(SellerInfo seller : sellerList) {
	    			seller.setStatus("0");  //解封
	    			sellerService.save(seller);
	    		}
	    		return ResponseResult.success(null);
			}else {
				return ResponseResult.fail(Constants.RESP_TOKEN_TIMEOUT, "未登录或登录超时");
			}
		}else {
			return ResponseResult.fail(Constants.RESP_FAIL, "签名校验失败");
		}
    }
    
    
    @ApiOperation(value = "获取公众号操作日志")
    @PostMapping(path = "/get_pub_no_operlog/{id}")
    public ResponseResult<List<OperLog>> get_pub_no_operlog(@PathVariable int id,@RequestBody @Valid TokenVO paramVo,BindingResult errors) {
    	if (errors.hasErrors()){  //参数校验失败
			//返回参数校验错误信息
    		return ResponseResult.fail(Constants.RESP_FAIL, errors.getAllErrors().get(0).getDefaultMessage());
	    }
    	//校验sign字符串
    	Map<String, Object> signMap = new HashMap<String, Object>();
		signMap.put("token", paramVo.getToken());
		String paramStr = SortUtils.sortMap(signMap);
		boolean flag = validateSign(paramStr, paramVo.getSign());
		log.info("验证签名结果：" + flag);
		if(flag){
	    	Object userObj = getUserByToken(paramVo.getToken());
			if(userObj!=null) {
	    		List<OperLog> operLogList = operLogService.getOperLogByOperObj(id);
	    		return ResponseResult.success(operLogList);
			}else {
				return ResponseResult.fail(Constants.RESP_TOKEN_TIMEOUT, "未登录或登录超时");
			}
		}else {
			return ResponseResult.fail(Constants.RESP_FAIL, "签名校验失败");
		}	
    }
    
    @ApiOperation(value = "获取公众号列表")
    @PostMapping(path = "/get_pub_no_page")
    public ResponseResult<Page<WxPubNo>> get_pub_no_page(@RequestBody @Valid PageVO paramVo,BindingResult errors) {
    	if (errors.hasErrors()){  //参数校验失败
			//返回参数校验错误信息
    		return ResponseResult.fail(Constants.RESP_FAIL, errors.getAllErrors().get(0).getDefaultMessage());
	    }
    	//校验sign字符串
    	Map<String, Object> signMap = MapTrunPojoUtils.object2Map(paramVo);
		signMap.put("token", paramVo.getToken());
		String paramStr = SortUtils.sortMap(signMap);
		boolean flag = validateSign(paramStr, paramVo.getSign());
		log.info("验证签名结果：" + flag);
		if(flag){
	    	Object userObj = getUserByToken(paramVo.getToken());
			if(userObj!=null) {
	    		Sort sort = new Sort(Sort.Direction.DESC,"createTime"); //创建时间降序排序
	    		Pageable pageable = PageRequest.of(paramVo.getPageNo(), paramVo.getPageSize(), sort);
	    		Page<WxPubNo> wxPubNoList = wxPubNoService.findAll(pageable);
	    		return ResponseResult.success(wxPubNoList);
			}else {
				return ResponseResult.fail(Constants.RESP_TOKEN_TIMEOUT, "未登录或登录超时");
			}
		}else {
			return ResponseResult.fail(Constants.RESP_FAIL, "签名校验失败");
		}	
    }
    
    @ApiOperation(value = "获取公众号详情")
    @PostMapping(path = "/get_pub_no_detail")
    public ResponseResult<WxPubNo> get_pub_no_detail(@PathVariable int id,@RequestBody @Valid TokenVO paramVo,BindingResult errors) {
    	if (errors.hasErrors()){  //参数校验失败
			//返回参数校验错误信息
    		return ResponseResult.fail(Constants.RESP_FAIL, errors.getAllErrors().get(0).getDefaultMessage());
	    }
    	//校验sign字符串
    	Map<String, Object> signMap = new HashMap<String, Object>();
    	signMap.put("id", id);
		signMap.put("token", paramVo.getToken());
		String paramStr = SortUtils.sortMap(signMap);
		boolean flag = validateSign(paramStr, paramVo.getSign());
		log.info("验证签名结果：" + flag);
		if(flag){
			Object userObj = getUserByToken(paramVo.getToken());
			if(userObj!=null) {
	    		WxPubNo wxPubNo = wxPubNoService.getWxPubNo(id);
	    		//如果公众号的状态是修改中，就返回提交修改的信息
	    		if(wxPubNo.getStatus().equals(WxPubNoStatus.editing.getCode())) {
	    			WxPubNoExam wxPubNoExam = wxPubNoExamService.findById(id);
	    			WxPubNoExamVO wxPubNoExamVO = new WxPubNoExamVO();
	    			BeanUtils.copyProperties(wxPubNoExam, wxPubNoExamVO);
	    			BeanUtils.copyProperties(wxPubNoExamVO, wxPubNo);
	    		}
	    		return ResponseResult.success(wxPubNo);
			}else {
				return ResponseResult.fail(Constants.RESP_TOKEN_TIMEOUT, "未登录或登录超时");
			}
		}else {
			return ResponseResult.fail(Constants.RESP_FAIL, "签名校验失败");
		}	
    }
    
    @ApiOperation(value = "审核公众号")
    @PostMapping(path = "/emam_pub_no")
    public ResponseResult emam_pub_no(@RequestBody @Valid ExamPubNoVO paramVo, BindingResult errors) {
    	if (errors.hasErrors()){  //参数校验失败
			//返回参数校验错误信息
    		return ResponseResult.fail(Constants.RESP_FAIL, errors.getAllErrors().get(0).getDefaultMessage());
	    }
    	//校验sign字符串
    	Map<String, Object> signMap = MapTrunPojoUtils.object2Map(paramVo);
		signMap.put("token", paramVo.getToken());
		String paramStr = SortUtils.sortMap(signMap);
		boolean flag = validateSign(paramStr, paramVo.getSign());
		log.info("验证签名结果：" + flag);
		if(flag){
			Object userObj = getUserByToken(paramVo.getToken());
			if(userObj!=null) {
				JSONObject jsonObj = JSONObject.parseObject(userObj.toString());
	    		AdmUser user = JSONObject.toJavaObject(jsonObj, AdmUser.class);
	    		
	    		wxPubNoService.examPubNo(paramVo, user.getId());
	    		return ResponseResult.success(null);
			}else {
				return ResponseResult.fail(Constants.RESP_TOKEN_TIMEOUT, "未登录或登录超时");
			}
		}else {
			return ResponseResult.fail(Constants.RESP_FAIL, "签名校验失败");
		}	
    }
    
    @ApiOperation(value = "强制下架公众号")
    @PostMapping(path = "/down_pub_no/{id}")
    public ResponseResult down_pub_no(@PathVariable int id,@RequestBody @Valid TokenVO paramVo,BindingResult errors) {
    	if (errors.hasErrors()){  //参数校验失败
			//返回参数校验错误信息
    		return ResponseResult.fail(Constants.RESP_FAIL, errors.getAllErrors().get(0).getDefaultMessage());
	    }	
    	//校验sign字符串
		Map<String, Object> signMap = new HashMap<String, Object>();
		signMap.put("id", id);
		signMap.put("token", paramVo.getToken());
		String paramStr = SortUtils.sortMap(signMap);
		boolean flag = validateSign(paramStr, paramVo.getSign());
		log.info("验证签名结果：" + flag);
		if(flag){
			Object userObj = getUserByToken(paramVo.getToken());
			if(userObj!=null) {
				JSONObject jsonObj = JSONObject.parseObject(userObj.toString());
	    		AdmUser user = JSONObject.toJavaObject(jsonObj, AdmUser.class);
	    		
				//新增操作日志
				operLogService.addOperLog(id, "下架", "强制下架公众号", user.getId());
				return ResponseResult.success(null);
			}else {
				return ResponseResult.fail(Constants.RESP_TOKEN_TIMEOUT, "未登录或登录超时");
			}
		}else {
			return ResponseResult.fail(Constants.RESP_FAIL, "签名校验失败");
		}		
    }
    
}
